import java.util.LinkedList;

/**
 * @description:
 * @author: asd
 * @time: 2022/10/20 2:05
 */
//单条消息
final class Message{
    private int id;
    private String message;

    public Message(int id, String message) {
        this.id = id;
        this.message = message;
    }

    public int getId() {
        return id;
    }

    public String getMessage() {
        return message;
    }
}

//消息队列
class MessageQueue{
    private static LinkedList<Message> list = new LinkedList();
    private int capacity; //队列容量

    public MessageQueue(int capacity) {
        this.capacity = capacity;
    }

    //生产者
    public void productor(Message message){
        synchronized (list){
            while (list.size() == capacity){
                try {
                    System.out.println("队列已满，生产者线程等待");
                    list.wait(); //消息队列满，无法生产
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            list.addLast(message); //消息队列未满，入队添加
            list.notifyAll(); //唤醒waitSet中线程
            System.out.println("product message:"+message.getMessage()+",id:"+message.getId());
        }
    }

    //消费者
    public void consumer(){
        synchronized (list){
            while (list.size() == 0){
                try {
                    System.out.println("队列为空，消费者线程等待");
                    list.wait(); //消息队列空，无法消费
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            Message message = list.removeFirst(); //消息队列不空，出队移除
            list.notifyAll(); //唤醒waitSet中线程
            System.out.println("consume message:"+message.getMessage()+",id:"+message.getId());
        }
    }
}

public class ConsumerPro {
    public static void main(String[] args) {
        MessageQueue queue = new MessageQueue(2); //初始队列容量为2
        for (int i = 0; i < 5; i++) {
            int id = i;
            new Thread(()->{
                queue.productor(new Message(id,"message"+id));
            },"productor"+id).start(); //每个消息对应一个线程启动
        }
        new Thread(()->{
            while (true){
                try {
                    Thread.sleep(1000);
                    queue.consumer();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"consumer").start(); //线程启动
    }
}
